package com.maben.security.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.maben.security.pojo.UserPO;
import com.maben.security.service.UserService;
import com.maben.security.util.CustomUserDetails;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.ClassPathResource;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

/**
 * user业务类
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService, UserDetailsService {
    //根据username获取用户，这里不能加权限，登录接口调用
    @Override
    public UserPO getByUsername(String username) throws Exception {
        final List<UserPO> userPOS = listUsers();
        for (UserPO userPO : userPOS) {
            if (StringUtils.equalsIgnoreCase(userPO.getUsername(),username)){
                return userPO;
            }
        }
        return null;
    }

    // 仅拥有 "user:query" 权限的用户可调用
    @PreAuthorize("hasAuthority('user:search')")
    public List<UserPO> listUsers() throws Exception {
        final URL resource = ResourceUtil.getResource("json/user.json");
        final String jsonStr = FileUtil.readString(resource.getPath(), StandardCharsets.UTF_8);
        final JSONArray array = JSONUtil.parseArray(jsonStr);
        return array.stream().map(item -> JSONUtil.toBean((JSONObject) item, UserPO.class)).collect(Collectors.toList());
    }

    // 仅 ADMIN 角色可调用（角色前缀默认是 "ROLE_"，注解中可省略）
    @PreAuthorize("hasRole('ADMIN')")
    public void deleteUser(Long id) throws Exception {
        final List<UserPO> userPOS = listUsers();
        final List<UserPO> collect = userPOS.stream().filter(item -> !item.getId().equals(id)).collect(Collectors.toList());
        final String jsonStr = JSONUtil.toJsonStr(collect);
        final URL resource = ResourceUtil.getResource("json/user.json");
        FileUtil.writeString(jsonStr, resource.getPath(), StandardCharsets.UTF_8);
    }

    // 复杂条件：ADMIN 角色 或 拥有 "user:update" 权限
    @PreAuthorize("hasRole('ADMIN') or hasAuthority('user:update')")
    public void updateUser(UserPO user) throws Exception {
        final List<UserPO> userPOS = listUsers();
        userPOS.stream().filter(item -> item.getId().equals(user.getId())).forEach(item -> {
            item.setDesc(user.getDesc());
            if (StringUtils.isNotBlank(user.getUsername())) {
                item.setUsername(user.getUsername());
            }
            if (StringUtils.isNotBlank(user.getPassword())) {
                item.setPassword(user.getPassword());
            }
        });
    }


    //重写security获取user的方法
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        final ClassPathResource resource = new ClassPathResource("json/user.json");
        String jsonString = null;
        try (InputStream is = resource.getInputStream()) {
            // 例如：转为字符串（需处理IO异常）
            jsonString = IOUtils.toString(is, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("获取用户信息失败");
            throw new UsernameNotFoundException("获取用户信息失败");
        }
        final JSONArray jsonArray = JSONUtil.parseArray(jsonString);
        if (jsonArray.size() == 0) {
            throw new UsernameNotFoundException("用户不存在");
        }
        UserPO userPO = null;
        for (Object o : jsonArray) {
            final JSONObject json = (JSONObject) o;
            if (StringUtils.equalsIgnoreCase(json.getStr("username"), username)) {
                userPO = JSONUtil.toBean(json,UserPO.class);
                break;
            }
        }
        // 从数据库查询用户
        if (userPO == null) {
            throw new UsernameNotFoundException("用户不存在");
        }
        // 封装为 UserDetails 返回
        return new CustomUserDetails(userPO);
    }
}